package nl.saxion.act.bus;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Scanner;

import nl.saxion.act.logging.Assert;
import nl.saxion.act.logging.EasyLog;
import android.content.res.Resources;

public class Route
{
    private List<Locatie>            routepunten = new ArrayList<Locatie>();
    private Map<Locatie, HalteProxy> haltes      = new HashMap<Locatie, HalteProxy>();
    Resources resources;

    public Route( Resources aResources )
    {
        resources = aResources;
    }

    public Locatie getStartpunt()
    {
    	Assert.check( routepunten != null,    "Fout, geen routepuntenlijst beschikbaar "               );
    	Assert.check( routepunten.size() > 0, "Fout, routepunten leeg dus geen startpunt beschikbaar " );
        
        return routepunten.get( 0 );
    }
    
    public List<Locatie> getRoutepunten() {
        return routepunten;
    }

    public HalteProxy getHalte( Locatie locatie )
    {
    	Assert.check( isHalte( locatie ), "Fout, op deze locatie is geen halte " );
        return haltes.get( locatie );
    }
    
     public boolean isHalte( Locatie locatie ) 
    {
        return haltes.containsKey( locatie );
    }
    
   public void readRoute( Buswereld busWorld )
    {
        routepunten.clear();
        try {
        	InputStream inputStream = resources.openRawResource( R.raw.route );
            Scanner scanner = new Scanner( inputStream );
            Locatie routepunt = null;
            HalteProxy halte = null;
            while ( scanner.hasNextLine() ) {
                if ( scanner.hasNext() ) {
                    String tag = scanner.next(); // de tag beschrijft wat er op de regel te vinden is
                    if ( tag.equalsIgnoreCase( "Locatie"  ) ) {
                    	halte = null;
                        routepunt = leesRoutepunt( scanner );
                    } else if ( tag.equalsIgnoreCase( "Halte" ) ) {
                        halte = leesHalte( scanner, routepunt, busWorld );
                    } else if ( tag.equalsIgnoreCase( "Reiziger"  ) ) {
                        leesReizigerBijHalte( scanner, halte );
                    } else {
                    	EasyLog.v( "onbekende tag gelezen: '" + tag + "'" );
                    }
                    scanner.nextLine();
                }
            }
        } catch ( NoSuchElementException exception ) {
            throw exception;
        }
    }

	private void leesReizigerBijHalte(Scanner scanner, HalteProxy halte) {
    	Assert.check( halte != null, "leesfout, geen halte voor de reiziger" );

    	String   naam       = scanner.next();
		String   bestemming = scanner.next();
		halte.add( new Reiziger( naam, bestemming ) );

		EasyLog.i( "Ingelezen Reiziger '" + naam + " met bestemming '" + bestemming + "'" );
	}

	private HalteProxy leesHalte(Scanner scanner, Locatie routepunt, Buswereld busWorld ) {
    	Assert.check( routepunt != null, "leesfout, geen routepunt voor halte" );
		
		String     naam  = scanner.next();
		HalteProxy halte = new HalteProxy( naam, routepunt, busWorld );
		haltes.put( routepunt, halte );
		busWorld.addActor( halte );

		EasyLog.i( "Ingelezen Halte '" + naam + "'" );

		return halte;
	}

	private Locatie leesRoutepunt( Scanner scanner ) {
		double x          = Integer.parseInt( scanner.next() );  // much faster (~7x) than scanner.nextInt(), but why???
		double y          = Integer.parseInt( scanner.next() );  // much faster (~7x) than scanner.nextInt(), but why???
		Locatie routepunt = new Locatie( x, y );
		routepunten.add( routepunt );

		EasyLog.i( "Ingelezen routepunt (" + x + "," + y + ")" );

		return routepunt;
	}
}
